#ifndef ALENGINE_INCLUDED
#define ALENGINE_INCLUDED
#include <map>
#include <set>
#include <utils/TypeDefs.h>
#include <stdint.h>
#include "output/OpenAlContext.h"
#include "dataplugins/SoundData.h"
#include "output/Sound.h"

#define snd_buf_size 16

#define ptr_t std::ptrdiff_t
#define QWORD uint64_t

#include <output/thread.h>

class oal_engine;
class sound_thrd: public Thread
{
public:
    explicit    sound_thrd():Thread()
    {
        engine_caller = NULL;
    }
    void *ptr;
    void run();
    oal_engine *engine_caller;
};


class oal_engine
{
private:
    OpenAlContext context;
    QWORD curr_hndl;
    Sound *ptr_cast(ptr_t channel);
    std::map<ptr_t, SoundData *> snd_map; //contains associations between ptr_t and soundData
    std::set <ptr_t> snd_played; // contains pointers to sounds, which are played now
    void term_wrapper(std::pair<ptr_t, SoundData *> elem);

    sound_thrd *snd_thread;
    friend sound_thrd;
public:
    oal_engine();
    void Apply3D(float x, float y, float z);
    ptr_t create_channel(const char *fname, bool looping, bool playafter);//creating channel and register it
	void terminate_channel(ptr_t);
	void pause_channel(ptr_t);


    double channel_bytes2seconds(ptr_t hndl, QWORD bytes);
    QWORD channel_seconds2bytes(ptr_t hndl, double seconds);

    void channel_set_pos(ptr_t channel, QWORD pos);
    QWORD channel_get_pos(ptr_t channel);

    int channel_get_length(ptr_t channel); //in seconds
    void channel_set_volume(ptr_t channel, float volume);
    float channel_get_volume(ptr_t channel);
    ~oal_engine();
	
};


#endif
